// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
#include <bpf/libbpf.h>

static int libbpf_print_fn(enum libbpf_print_level level,
                           const char *fmt, va_list args)
{
    if (level == LIBBPF_DEBUG)
        return 0; // 忽略 DEBUG 级别
    return vfprintf(stderr, fmt, args);
}

int main(void)
{
    struct bpf_object *obj = NULL;
    int err = 0;

    libbpf_set_print(libbpf_print_fn);

    // 使用 LIBBPF_OPTS 宏自动填写 .sz
    LIBBPF_OPTS(bpf_object_open_opts, open_opts);

    obj = bpf_object__open_file("bpf_handle_try_charge_memcg.bpf.o", &open_opts);
    if (!obj) {
        fprintf(stderr, "Failed to open BPF object: %s\n", strerror(errno));
        return 1;
    }

    err = bpf_object__load(obj);
    if (err) {
        fprintf(stderr, "Failed to load BPF object: %d\n", err);
        goto out;
    }

    struct bpf_program *prog;
    bpf_object__for_each_program(prog, obj) {
        const char *sec = bpf_program__section_name(prog);
        if (!sec)
            continue;

        struct bpf_link *link = bpf_program__attach(prog);
        if (!link) {
            err = -errno;
            fprintf(stderr, "Attach failed for section %s: %s\n",
                    sec, strerror(errno));
            goto out;
        }
        // 简单示例，不保存 link，进程退出时自动清理
    }

    printf("BPF programs attached.\n");
    printf("Check output:\n  sudo cat /sys/kernel/debug/tracing/trace_pipe\n");

    while (1)
        sleep(60);

out:
    bpf_object__close(obj);
    return err != 0;
}